/*
Copyright 2010  Murali Devi (profdevi@gmail.com)

This file is part of ComineGL Project.

ComineGL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

ComineGL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with ComineGL.  If not, see <http://www.gnu.org/licenses/>.

This code uses the irrlicht and irrklang libraries.  Please read
the libraries copyrights at 

	irrlicht library:  http://irrlicht.sourceforge.net
	irrklang library:  http://www.ambiera.com/irrklang

*/



//v0.16 copyright Comine.com 20110925U18
#include <windows.h>
#include <stdarg.h>
#include "MStdLib.h"
#include "Global.h"
#include "ComineGLArrayInt.h"


//***********************************************
//** Exported Functions
//***********************************************
MDLLFUN bool CGLArrayIntLoad(int arrayid,int maxcapacity)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}
	
	// Check if fontid exists already
	if(GlobalIntArrayList.IsKey(arrayid)==true)
		{
		GlobalIntArrayList.Remove(arrayid);
		MStdPrintf("Removing Existing Int Array with id %d\n",arrayid);
		}

	TRefCount<MIntArray> *newarray=new TRefCount<MIntArray>;
	if(newarray==NULL)
		{
		MStdPrintf("**Unable to alloc memory\n");
		return false;
		}

	if(newarray->Create(0,maxcapacity)==false)
		{
		MStdPrintf("**Unable to init Int Array\n");
		newarray->Drop();
		return false;
		}
	
	// Add to the table
	if(GlobalIntArrayList.Add(arrayid,newarray)==false)
		{
		MStdPrintf("**Unable to add array id %d to int array table\n",arrayid);
		newarray->Drop();
		return false;
		}

	// Drop Reference to new int array
	newarray->Drop();

	MStdPrintf("Added Int Array as id %d with capacity %d integers\n",arrayid,maxcapacity);
	return true;
	}


///////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntExists(int arrayid)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}
	
	return GlobalIntArrayList.IsKey(arrayid);
	}


///////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntUnload(int arrayid)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	if(GlobalFontList.Remove(arrayid)==false)
		{
		MStdPrintf("**Unable to unload Int Array %d\n",arrayid);
		return false;
		}

	return true;	
	}


///////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntUnloadAll(void)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	if(GlobalIntArrayList.Clear()==false)
		{
		MStdPrintf("**Unable to clear all the Int Array Objects",__LINE__);
		return false;
		}	
	
	return true;
	}


/////////////////////////////////////////////////////
MDLLFUN int CGLArrayIntGetCount(void)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return 0;
		}

	return GlobalIntArrayList.GetCount();
	}


/////////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntInsert(int arrayid,int item)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}

	if(arrayobj->Insert(item)==false)
		{
		MStdPrintf("**Unable to insert item %d into array id %d\n",item,arrayid);
		return false;
		}

	return true;
	}


/////////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntInsertAt(int arrayid,int index,int item)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}

	if(arrayobj->Insert(index,item)==false)
		{
		MStdPrintf("**Unable to insert item %d into array id %d\n",item,arrayid);
		return false;
		}

	return true;
	}


///////////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntRemoveAt(int arrayid,int index)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}

	if(arrayobj->Remove(index)==false)
		{
		MStdPrintf("**Unable to remove item at index %d in array\n",index,arrayid);
		return false;
		}

	return true;
	}


/////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntRemoveValue(int arrayid,int val)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}
	
	const int length=arrayobj->GetCount();
	int i;
	for(i=0;i<length;++i)
		{
		if(arrayobj->Get(i)==val)
			{
			arrayobj->Remove(i);
			return true;
			}
		}
	
	return false;
	}


/////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntRemoveValueAll(int arrayid,int val)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}
	
	const int length=arrayobj->GetCount();
	int i;
	for(i=length-1;i>=0;--i)
		{
		if(arrayobj->Get(i)==val)
			{
			arrayobj->Remove(i);
			}
		}
	
	return false;
	}


/////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntRemoveLast(int arrayid)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}
	
	const int length=arrayobj->GetCount();
	if(length<=0)
		{
		return true;
		}

	if(arrayobj->Remove(length-1)==false)
		{
		return false;
		}

	return true;
	}


/////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntClear(int arrayid)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}

	if(arrayobj->Clear()==false)
		{
		MStdPrintf("**Unable to clear int array id %d\n",arrayid);
		return false;
		}

	return true;
	}


/////////////////////////////////////////////////////////
MDLLFUN int CGLArrayIntGetLength(int arrayid)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}

	return arrayobj->GetCount();
	}


////////////////////////////////////////////////////////
MDLLFUN int CGLArrayIntGetCapacity(int arrayid)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}

	return arrayobj->GetMaxCapacity();
	}


//////////////////////////////////////////////////////
MDLLFUN int CGLArrayIntGetAt(int arrayid,int index)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}

	const int length=arrayobj->GetCount();

	if(arrayid<0 || arrayid>=length)
		{
		MStdPrintf("**Index is out of bounds for Int Array id %d\n",arrayid);
		return 0;
		}

	return arrayobj->Get(index);
	}


///////////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntIsMember(int arrayid,int val)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}

	const int length=arrayobj->GetCount();
	int i;
	for(i=0;i<length;++i)
		{
		if(arrayobj->Get(i)==val)
			{
			return true;
			}
		}

	return false;
	}


///////////////////////////////////////////////////////////
MDLLFUN bool CGLArrayIntPrint(int arrayid)
	{
	if(GlobalInitialized==false)
		{
		MStdPrintf("**Engine is not initialized\n");
		return false;
		}

	MIntArray *arrayobj=GlobalIntArrayList.Find(arrayid);
	if(arrayobj==NULL)
		{
		MStdPrintf("**No Int Array with id %d\n",arrayid);
		return false;
		}
	
	MStdPrintf("Int Array %d Contents: ",arrayid);
	arrayobj->Print();

	return true;
	}

